home *** CD-ROM | disk | FTP | other *** search
- /*
- * dltogl.c -- convert .DL animations into .GL animations.
- *
- * usage: dltogl file.dl [file.gl]
- *
- * If no .gl file is specified, the images and control file will be
- * written to separate files. The control file will always be "dl.txt",
- * the images "clpN.clp" and a palette file called "palette.pic".
- *
- * Author:
- * George Phillips
- * <phillips@cs.ubc.ca>
- */
-
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "dltogl_protos.h"
-
- #define FOW "wb"
-
- FILE* gl;
- int gl_fileno;
-
- FILE* file_open();
- int file_close();
-
- #define isneg16(x) ((x) & 0x8000)
- #define neg16(x) ((~(x) + 1) & 0x7fff)
-
- main(argc, argv)
- int argc;
- char* argv[];
- {
- unsigned int i, j;
- FILE* fp;
- int num_scrn;
- int ctl_len;
- int format;
- static char title[21];
- static char author[21];
- static unsigned char pal[256*3];
- unsigned char* screen;
- static unsigned char halfscreen[160*100];
- static char fname[32];
- int picnum;
- int images_per_screen;
- FILE* ctl;
- int fx, fy;
- int* cmd;
- int labelpos;
- int cmdnum;
-
- if (argc != 2 && argc != 3)
- die("usage: dltogl file.dl [file.gl]");
-
- if (!(fp = fopen(argv[1], "rb"))) {
- fprintf(stderr, "dltogl: can't open %s\n", argv[1]);
- exit(1);
- }
-
- gl = 0;
- gl_fileno = 0;
- if (argc == 3 && !(gl = fopen(argv[2], FOW))) {
- fprintf(stderr, "dltogl: can't open %s for writing\n", argv[2]);
- exit(1);
- }
-
- if (fgetc(fp) != 2)
- die("dltogl: only version 2 files can be handled");
-
- switch (format = fgetc(fp)) {
- case 0:
- fx = fy = 0;
- images_per_screen = 1;
- break;
- case 1:
- fx = 80;
- fy = 50;
- images_per_screen = 4;
- break;
- default:
- die("dltogl: only large and medium formats are handled");
- break;
- }
-
- title[20] = author[20] = 0;
- for (i = 0; i < 20; i++)
- title[i] = fgetc(fp) ^ 255;
-
- for (i = 0; i < 20; i++)
- author[i] = fgetc(fp) ^ 255;
-
- for (i = 0; i < 20; i++) {
- if ((unsigned char)title[i] == 255) title[i] = 0;
- if ((unsigned char)author[i] == 255) author[i] = 0;
- }
-
- num_scrn = fgetc(fp);
- ctl_len = fgetc(fp);
-
- if (!(cmd = (int*)malloc(ctl_len * sizeof(int))))
- die("dltogl: out of memory");
-
- gl_numfiles(num_scrn * images_per_screen + 1 + 1);
-
- /* mebbe this is the border colour? */
- for (i = 0; i < 3; i++)
- fgetc(fp);
-
- for (i = 0; i < 256; i++) {
- pal[i*3] = fgetc(fp);
- pal[i*3+1] = fgetc(fp);
- pal[i*3+2] = fgetc(fp);
- }
-
- if (!(screen = malloc(320 * 200)))
- die("dltogl: not enough memory.");
-
- memset(screen, 0, 320 * 200);
- writepic(screen, 320, 200, "palette.pic", pal);
-
- picnum = 0;
- for (j = 0; j < num_scrn; j++) {
- fread(screen, 320 * 200, 1, fp);
- switch (format) {
- case 0: /* large */
- sprintf(fname, "clp%d.clp", picnum++);
- writepic(screen, 320, 200, fname, (unsigned char*)0);
- break;
- case 1: /* medium */
- for (i = 0; i < 4; i++) {
- unsigned char* src;
- unsigned char* dst;
- int row;
- int col;
-
- sprintf(fname, "clp%d.clp", picnum++);
- src = screen + (i % 2) * 160 + (i / 2) * 100 * 320;
- dst = halfscreen;
- for (row = 0; row < 100; row++) {
- for (col = 0; col < 160; col++)
- *dst++ = *src++;
- src += 160;
- }
- writepic(halfscreen, 160, 100, fname, (unsigned char*)0);
- }
- }
- }
-
- ctl = file_open("dl.txt", FOW);
-
- fprintf(ctl, "; This GL file was converted from DL format by dltogl\r\n");
- fprintf(ctl, "; Title: %s\r\n", title);
- fprintf(ctl, "; Author: %s\r\n", author);
- /* could print all the other keeno information */
-
- fprintf(ctl, "video l\r\n");
- fprintf(ctl, "pload palette,1\r\n");
- fprintf(ctl, "palette 1\r\n");
- fprintf(ctl, "pfree 1\r\n");
- for (i = 0; i < num_scrn * images_per_screen; i++)
- fprintf(ctl, "cload clp%d,%d\r\n", i, i + 1);
-
- for (i = 0; i < ctl_len; i++) {
- j = fgetc(fp);
- j += fgetc(fp) << 8;
- cmd[i] = j;
- }
-
- labelpos = 0;
- if (isneg16(cmd[ctl_len - 1])) {
- labelpos = neg16(cmd[ctl_len - 1]) + 1;
- ctl_len--; /* ignore that last command */
- }
-
- for (i = 0, cmdnum = 0; i < ctl_len; i++, cmdnum++) {
- if (cmdnum == labelpos)
- fprintf(ctl, "forever:\r\n");
- if (isneg16(cmd[i])) {
- i++;
- fprintf(ctl, "waitkey %d\r\n", cmd[i]);
- }
- else
- fprintf(ctl, "putup %d,%d,%d,10\r\n", fx, fy, cmd[i] + 1);
- }
- fprintf(ctl, "goto forever\r\n");
- fputc(26, ctl);
- file_close(ctl);
-
- fclose(fp);
-
- if (gl)
- fclose(gl);
-
- exit(0);
- }
-
- void die(s)
- char*s;
- {
- fprintf(stderr,"%s\n",s);
- exit(1);
- }
-
- #define BLOCKSIZE (8192)
-
- void writepic(pixel, width, height, filename, cmap)
- unsigned char* pixel;
- int width;
- int height;
- char* filename;
- unsigned char* cmap;
- {
- FILE* fp;
- unsigned int i;
- static unsigned char buf[BLOCKSIZE];
- unsigned char* p;
- int row, col;
-
- fp = file_open(filename, FOW);
-
- /* write header */
- writeshort(fp, 0x1234); /* magic number */
- writeshort(fp, width);
- writeshort(fp, height);
- writeshort(fp, 0);
- writeshort(fp, 0);
- fputc(8, fp); /* bits per pixel */
- fputc(0xff, fp); /* byte here is always 255 */
- fputc('L', fp); /* video mode */
- if (cmap) {
- writeshort(fp, 4); /* extra information descriptor */
- writeshort(fp, 768); /* extra information length */
- fwrite(cmap, 768, 1, fp);
- }
- else {
- writeshort(fp, 0);
- writeshort(fp, 0);
- }
-
- /* number of packed blocks in file */
- writeshort(fp, ((long)width * height + BLOCKSIZE - 1) / BLOCKSIZE);
-
- i = 0;
- for (row = height - 1; row >= 0; row--) {
- p = pixel + row * width;
- for (col = 0; col < width; col++) {
- buf[i++] = *p++;
- if (i == BLOCKSIZE) {
- outpackblock(fp, buf, i);
- i = 0;
- }
- }
- }
- if (i > 0)
- outpackblock(fp, buf, i);
-
- file_close(fp);
- }
-
- void outpackblock(fp, buf, len)
- FILE* fp;
- char* buf;
- int len;
- {
- static char packbuf[BLOCKSIZE * 4 - 1]; /* overkill */
- int packlen;
-
- packlen = packblock(buf, packbuf, len);
- fwrite(packbuf, packlen, 1, fp);
- }
-
- int packblock(src, dest, len)
- char* src;
- char* dest;
- int len;
- {
- unsigned char* s;
- unsigned char* r;
- unsigned char* d;
- static int overhead[256];
- int i;
- int esc;
- int escpresent;
- int minover;
- int packlen;
-
- for (i = 0; i < 256; i++)
- overhead[i] = 0;
-
- /* do first pass to find optimal esc byte */
- for (s = src; s < src + len; s = r) {
- for (r = s; *r == *s && r < src + len; r++)
- ;
- if (r - s < 4)
- overhead[*s]++;
- }
-
- minover = len + 1;
- for (i = 0; i < 256; i++) {
- if (overhead[i] < minover) {
- minover = overhead[i];
- esc = i;
- }
- }
- escpresent = overhead[esc] == 0;
-
- /* now run-length encode on the second pass */
-
- d = dest + 5;
- for (s = src; s < src + len; s = r) {
- for (r = s; *r == *s && r < src + len; r++)
- ;
- if (r - s < 4 && (!escpresent || *s != esc)) {
- while (s < r)
- *d++ = *s++;
- }
- else {
- if (r - s > 255) {
- *d++ = esc;
- *d++ = 0;
- *d++ = (r - s) & 0xff;
- *d++ = ((r - s) >> 8) & 0xff;
- *d++ = *s++;
- }
- else {
- *d++ = esc;
- *d++ = r - s;
- *d++ = *s++;
- }
- }
- }
-
- packlen = d - dest;
-
- /* fill in the block header */
-
- *dest++ = packlen & 0xff; /* packed block size */
- *dest++ = ((packlen) >> 8) & 0xff;
- *dest++ = len & 0xff;
- *dest++ = (len >> 8) & 0xff; /* unpacked block size */
- *dest++ = esc; /* escape byte */
-
- return packlen;
- }
-
- void writeshort(fp, s)
- FILE* fp;
- int s;
- {
- fputc(s & 255, fp);
- fputc((s >> 8) & 255, fp);
- }
-
- void writelong(fp, l)
- FILE* fp;
- long l;
- {
- fputc(l & 255, fp);
- fputc((l >> 8) & 255, fp);
- fputc((l >> 16) & 255, fp);
- fputc((l >> 24) & 255, fp);
- }
-
- long gl_eof;
- long gl_filestart;
-
- void gl_numfiles(n)
- int n;
- {
- if (gl) {
- fseek(gl, 0, 0);
- writeshort(gl, n * 17);
- gl_eof = 2 + n * 17;
- }
- }
-
- FILE* file_open(name, mode)
- char* name;
- char* mode;
- {
- FILE* fp;
- char fname[14];
-
- if (!gl) {
- if (!(fp = fopen(name, mode))) {
- fprintf(stderr, "dltogl: can't open %s\n", name);
- exit(1);
- }
- return fp;
- }
-
- fseek(gl, 2 + gl_fileno++ * 17, 0);
- writelong(gl, gl_eof);
- memset(fname, 0, 13);
- strcpy(fname, name);
- fwrite(fname, 13, 1, gl);
- fseek(gl, gl_filestart = gl_eof + 4, 0);
- return gl;
- }
-
- int file_close(fp)
- FILE* fp;
- {
- if (!gl)
- return fclose(fp);
-
- gl_eof = ftell(gl);
- fseek(gl, gl_filestart - 4, 0);
- writelong(gl, gl_eof - gl_filestart);
- }
-
-